package com.taplinker.client.core;

import java.io.File;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map.Entry;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.taplinker.client.AppConfigContext;
import com.taplinker.client.im.domain.BindData;
import com.taplinker.core.cache.CacheOutException;
import com.taplinker.core.cache.MemCacheImpl;
import com.taplinker.core.rpc.Result;
import com.taplinker.core.rpc.command.SimpleBaseCommand;
import com.taplinker.core.rpc.http.HttpTemplate;
import com.taplinker.core.rpc.http.client.cache.CacheKey;
import com.taplinker.core.rpc.http.client.cache.HttpCacheDAO;
import com.taplinker.core.rpc.http.client.cache.HttpCacheItem;
import com.taplinker.core.util.LogUtil;

public class ImageManager{
	 
	private MemCacheImpl memCache;
	private static ImageManager instance;
	public static ImageManager getInstance() {
		if (instance!=null) return instance;
		synchronized (ImageManager.class) {
			if (instance==null) {
				instance = new ImageManager();
			}
		}
		return instance;
	}
	
	public void initialize(Context context) {
		memCache = new MemCacheImpl(context);
		memCache.mallocSpace();
	}
	
	class UrlView {
		private WeakReference<ImageView> view;
		public UrlView(ImageView imageView)
		{
			view = new WeakReference<ImageView>(imageView);
		}
	}
	
	private HashMap<String, LinkedList<UrlView>> urlDownloadMap = new HashMap<String, LinkedList<UrlView>>();
	
	public void loadImage(final String url, final ImageView imageView,
			final int width, final int height, LocalCallBack callBack) {
		if (url == null){
			return;
		}
		Log.d("log", "图片链接："+url);
		String cachekey = CacheKey.getCacheKey(url);
		if (imageView != null) {
			imageView.setImageBitmap(null);
		}
		Bitmap bitmap = null;
		if (memCache != null) {
			bitmap = memCache.readCache(cachekey);
		}

		if (bitmap != null) {
			Log.d("log", "此图片链接有缓存, 直接获取缓存文件!");
			imageView.setImageBitmap(bitmap);
			return;
		}

		removeView(imageView);

		if (urlDownloadMap.get(url) != null) {
			LogUtil.d("http", "url is downloading ");
			urlDownloadMap.get(url).add(new UrlView(imageView));
			return;
		} else {
			LogUtil.d("http", "url download started ");
			LinkedList<UrlView> list = new LinkedList<UrlView>();
			list.add(new UrlView(imageView));
			urlDownloadMap.put(url, list);
		}

		new ImageDownloadCommand(url, null, width, height, callBack).execute();
	}
	
	private void removeView(ImageView imageView)
	{
		Iterator<Entry<String, LinkedList<UrlView>>> iter = urlDownloadMap.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String, LinkedList<UrlView>> entity = iter.next();
			if(entity.getValue() == null)
				return;
			Iterator<UrlView> listIterator = entity.getValue().iterator();
			while(listIterator.hasNext())
			{
				if(listIterator.next().view.get() == imageView)
				{
					LogUtil.d("http", "imageview is replaced ");
					listIterator.remove();
				}
			}
		}
	}
	
    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }

            final float totalPixels = width * height;
            final float totalReqPixelsCap = reqWidth * reqHeight * 2;

            while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                inSampleSize++;
            }
        }
        return inSampleSize;
    }
    
    private Bitmap decodeSampledBitmapFromResource(String in,int reqWidth, int reqHeight) {
	    // 首先设置 inJustDecodeBounds=true 来检查尺寸
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    BitmapFactory.decodeFile(in, options);
	    // 计算压缩比例
	    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
	  
	    // 设置inJustDecodeBounds为false
	    options.inJustDecodeBounds = false;
	    
	    Bitmap bitmap = BitmapFactory.decodeFile(in, options);
	    
	    LogUtil.d("http", reqWidth + "," + reqHeight);
	    LogUtil.d("http", bitmap.getWidth() + "," + bitmap.getHeight());
	    return bitmap;
	}
    
    class ImageDownloadCommand extends SimpleBaseCommand{

    	private String url;
    	private WeakReference<ImageView> view;
    	private int width;
    	private int height;
    	private LocalCallBack callBack;
    	public ImageDownloadCommand(String url,View view, int width, int height, LocalCallBack callBack) {
    		this.url = url;
    		this.view = new WeakReference<ImageView>((ImageView) view);
    		this.width = width;
    		this.height = height;
    		this.callBack = callBack;
    	}
    	
    	@Override
    	public Result go() {
    		Result result = new Result();
    		String requestUrl  = url;
    		try  {
    			LogUtil.d("http", "图片链接："+url);
    			// 截掉"?"之后
    			requestUrl = requestUrl.substring(0, requestUrl.indexOf("?"));
    			if(url.contains("http://")) {
    				LogUtil.d("http", "get from remote");
    				HttpCacheItem item = HttpCacheDAO.getInstance().getFileIndexItem(CacheKey.getCacheKey(new URL(requestUrl).getPath()));
        			if(item != null&&!item.isTemp()){
        				
        				requestUrl = item.getPath();
        			}else{
        				requestUrl = new HttpTemplate().download(url, this).object.toString();
        			}
    			}
    			Log.v("log_ktian", "呵呵:"+requestUrl);
				result.object = decodeSampledBitmapFromResource(requestUrl,width, height);
				
    		} catch(Exception e) {
    			Log.v("log_ktian", "呵呵111:"+requestUrl);
    			Log.d("log_ktian", "下载异常");
    		} 
			return result;
    		
    	}
    	

    	@Override
		protected void update(long planSize, long curSize) {
    		if(callBack != null) {
    			callBack.updateProgres(planSize, curSize);
    		}
		}

		@Override
    	public void yes(Result result) {
			try {
				Log.v("log_ktian", url+"-->头像下载完毕展示");
				LinkedList<UrlView> list = urlDownloadMap.remove(url);
				for(UrlView urlView:list)
				{
					if(urlView.view.get() != null)
						urlView.view.get().setImageBitmap((Bitmap) result.object);
				}
				if(view != null&&view.get()!= null) {
					view.get().setImageBitmap((Bitmap) result.object);
					LogUtil.d("http", "图片展示完成======================");
				}
				LogUtil.d("http", "图片展示完成");
				memCache.writeCache(CacheKey.getCacheKey(url), (Bitmap)result.object);
				if(callBack != null&&result.object!= null) {
					callBack.callBack(result.object);
				}
			} catch (CacheOutException e) {
				e.printStackTrace();
				Log.d("tag", result.message);
			}
    	}
    	
    	@Override
    	public void no(Result result) {
    		super.no(result);
    		urlDownloadMap.remove(url);
			Log.d("log_ktian", "下载失败");
    	}
    }
    
    public void uploadImage(File file, Context context, LocalCallBack localCallBack) {
		new UploadCommand(file, context, localCallBack).execute();
	}
    
    class UploadCommand extends SimpleBaseCommand{

    	private File file;
    	private LocalCallBack callBack;
    	public UploadCommand(File file,Context context, LocalCallBack callBack) {
    		super(context);
    		this.file = file;
    		this.callBack = callBack;
    	}
    	
    	public UploadCommand(String path, Context context) {
    		super(context);
    		file = new File(path);
    	}
    	
    	@Override
    	public Result go() {
    		Log.d("log", AppConfigContext.TAPLINKER_WEB + "/services/v2/upload");
    		return new HttpTemplate().upload(AppConfigContext.TAPLINKER_WEB
    				+ "/services/v2/upload"
    				,file,this);
    	}

    	@Override
    	public void yes(Result result) {
    		try {
    			if(callBack != null) {
    				callBack.callBack(result.object);
    			}
    			URL url = new URL(BindData.getInstance().getBaseUrl() +result.object.toString());
    			HttpCacheDAO.getInstance().insert(CacheKey.getCacheKey(url.getPath()), file.getPath(), 1, "false");
    			Log.d("tag", result.message);
    		}catch(Exception e){
    			
    		}
    	}

    	@Override
    	public void no(Result result) {
    		// TODO Auto-generated method stub
    		super.no(result);
System.out.println("no--->"+result.message);
System.out.println("no--->"+result.status);
System.out.println("no--->"+result.object);
    		callBack.no();
    	}
    	
    	@Override
    	protected void update(long planSize, long curSize) {
    		callBack.updateProgres(planSize, curSize);
    	}
    	
    }
    
	public interface LocalCallBack {
		public void callBack(Object obj);
		public void updateProgres(long planSize, long curSize);
		public void no();
	}
}
